home *** CD-ROM | disk | FTP | other *** search
/ Aminet 31 / Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso / Aminet / dev / c / vbccsrc.lha / vbcc / opt.c < prev    next >
C/C++ Source or Header  |  1999-03-07  |  27KB  |  648 lines

  1. /*  $VER: vbcc (opt.c) V0.4     */
  2. /*  allgemeine Routinen fuer den Optimizer und Steuerung der einzelnen  */
  3. /*  Laeufe                                                              */
  4.  
  5. #include "opt.h"
  6.  
  7. static char FILE_[]=__FILE__;
  8.  
  9. /*  die naechsten Funktionen sollten evtl. in ic.c                  */
  10.  
  11. /*  Sind use/change-Listen initialisiert?   */
  12. int have_alias;
  13.  
  14. void insert_IC(struct IC *p,struct IC *new)
  15. /*  fuegt new hinter p ein; p darf 0 sein                           */
  16. {
  17.     new->prev=p;
  18.     if(p){ new->next=p->next; p->next=new; }
  19.      else{ new->next=first_ic; first_ic=new; }
  20.     if(new->next) new->next->prev=new; else last_ic=new;
  21.     new->q1.am=new->q2.am=new->z.am=0;
  22. }
  23.  
  24. #ifndef NO_OPTIMIZER
  25.  
  26. int gchanged;   /*  Merker, ob Optimierungslauf etwas geaendert hat */
  27. int norek;      /*  diese Funktion wird nicht rekursiv auf          */
  28. int nocall;     /*  diese Funktion kehrt nicht zum Caller zurueck   */
  29.  
  30. /*  temporary fuer verschiedene Bitvektoren */
  31. unsigned char *tmp;
  32.  
  33. void recalc_offsets(struct flowgraph *fg)
  34. /*  berechnet Offsets fuer auto-Variablen neu und versucht, fuer Variablen, */
  35. /*  die nicht gleichzeitig aktiv sind, den gleichen Platz zu belegen        */
  36. {
  37.     int i,b,*eqto;size_t bsize;zlong *al,*sz;
  38.     unsigned char **used,*tmp,*empty;
  39.     struct IC *p;
  40.     if(DEBUG&1024) printf("recalculating offsets\n");
  41.     if(DEBUG&1024) printf("setting up arrays\n");
  42.     bsize=(basic_blocks+CHAR_BIT-1)/CHAR_BIT;
  43.     if(DEBUG&1024) printf("bsize=%lu\n",(unsigned long)bsize);
  44.     tmp=mymalloc(bsize);
  45.     al=mymalloc(sizeof(*al)*(vcount-rcount));
  46.     eqto=mymalloc(sizeof(int)*(vcount-rcount));
  47.     sz=mymalloc(sizeof(*sz)*(vcount-rcount));
  48.     empty=mymalloc(bsize);
  49.     memset(empty,0,bsize);
  50.     used=mymalloc(sizeof(unsigned char *)*(vcount-rcount));
  51.     /*  Tabelle, welche Variable in welchem Block belegt ist, aufbauen  */
  52.     for(i=0;i<vcount-rcount;i++){
  53.         if(zlleq(l2zl(0L),vilist[i]->offset)&&(vilist[i]->storage_class==AUTO||vilist[i]->storage_class==REGISTER)){
  54.             if(DEBUG&2048) printf("setting up for %s,%ld\n",vilist[i]->identifier,zl2l(vilist[i]->offset));
  55.             used[i]=mymalloc(bsize);
  56.             memset(used[i],0,bsize);
  57.         }else{
  58.             used[i]=0;
  59.         }
  60.         sz[i]=szof(vilist[i]->vtyp);
  61.         al[i]=falign(vilist[i]->vtyp);
  62.         eqto[i]=-1;
  63.     }
  64.     b=0;
  65.     while(fg){
  66.         if(b>=basic_blocks) ierror(0);
  67.         for(i=0;i<vcount-rcount;i++){
  68.             if(used[i]&&(BTST(fg->av_in,i)||BTST(fg->av_out,i))){
  69.                 int r;
  70.                 BSET(used[i],b);
  71.                 for(r=1;r<=MAXR;r++)
  72.                     if(fg->regv[r]&&fg->regv[r]->index==i) BCLR(used[i],b);
  73.             }
  74.         }
  75.         for(p=fg->start;p;p=p->next){
  76.             if((p->q1.flags&(VAR|REG))==VAR){
  77.                 i=p->q1.v->index;
  78.                 if(used[i]){
  79.                     BSET(used[i],b);
  80.                 }
  81.             }
  82.             if((p->q2.flags&(VAR|REG))==VAR){
  83.                 i=p->q2.v->index;
  84.                 if(used[i]){
  85.                     BSET(used[i],b);
  86.                 }
  87.             }
  88.             if((p->z.flags&(VAR|REG))==VAR){
  89.                 i=p->z.v->index;
  90.                 if(used[i]){
  91.                     BSET(used[i],b);
  92.                 }
  93.             }
  94.             if(p==fg->end) break;
  95.         }
  96.         fg=fg->normalout;
  97.         b++;
  98.     }
  99.     /*  schauen, ob Variablen in gleichen Speicher koennen  */
  100.     if(DEBUG&1024) printf("looking for distinct variables\n");
  101.     for(i=0;i<vcount-rcount;i++){
  102.         if(!used[i]||eqto[i]>=0) continue;
  103.         if(!memcmp(used[i],empty,bsize)){ free(used[i]);used[i]=0;continue;}
  104.         for(b=i+1;b<vcount-rcount;b++){
  105.             if(!used[b]||eqto[b]>=0) continue;
  106.             if(DEBUG&2048) printf("comparing %s(%ld) and %s(%ld)\n",vilist[i]->identifier,zl2l(vilist[i]->offset),vilist[b]->identifier,zl2l(vilist[b]->offset));
  107.  
  108.             memcpy(tmp,used[i],bsize);
  109.             bvintersect(tmp,used[b],bsize);
  110.             if(!memcmp(tmp,empty,bsize)){
  111.                 if(DEBUG&1024) printf("memory for %s(%ld) and %s(%ld) equal\n",vilist[i]->identifier,zl2l(vilist[i]->offset),vilist[b]->identifier,zl2l(vilist[b]->offset));
  112.                 eqto[b]=i;
  113.                 if(!zlleq(al[b],al[i])) al[i]=al[b];
  114.                 if(!zlleq(sz[b],sz[i])) sz[i]=sz[b];
  115.                 bvunite(used[i],used[b],bsize);
  116.             }
  117.         }
  118.     }
  119.     if(DEBUG&1024) printf("final recalculating\n");
  120.     max_offset=l2zl(0L);
  121.     for(i=0;i<vcount-rcount;i++){
  122.         if(!used[i]) continue;
  123.         free(used[i]);
  124.         if(DEBUG&2048) printf("adjusting offset for %s,%ld\n",vilist[i]->identifier,zl2l(vilist[i]->offset));
  125.         if(eqto[i]>=0){
  126.             vilist[i]->offset=vilist[eqto[i]]->offset;
  127.             continue;
  128.         }
  129.         vilist[i]->offset=zlmult(zldiv(zladd(max_offset,zlsub(al[i],l2zl(1L))),al[i]),al[i]);
  130.         max_offset=zladd(vilist[i]->offset,sz[i]);
  131.     }
  132.     free(used);
  133.     free(sz);
  134.     free(al);
  135.     free(tmp);
  136.     free(empty);
  137.     free(eqto);
  138. }
  139. void remove_IC_fg(struct flowgraph *g,struct IC *p)
  140. /*  Entfernt IC p und beachtet Flussgraph. Ausserdem werden             */
  141. /*  use/change-Listen freigegeben.                                      */
  142. {
  143.     if(p->q1.am||p->q2.am||p->z.am) ierror(0);
  144.     if(have_alias){
  145.         free(p->use_list);
  146.         free(p->change_list);
  147.     }
  148.     if(g->start==g->end){
  149.         g->start=g->end=0;
  150.     }else{
  151.         if(p==g->end) g->end=p->prev;
  152.         if(p==g->start) g->start=p->next;
  153.     }
  154.     remove_IC(p);
  155. }
  156.  
  157. int peephole(void)
  158. /*  macht alle moeglichen Vereinfachungen/Vereinheitlichungen   */
  159. {
  160.     struct IC *p;struct obj o;int t,c,null,eins,changed,done=0;
  161.     do{
  162.         if(DEBUG&1024) printf("searching for peephole optimizations\n");
  163.         changed=0;ic_count=0;
  164.         p=first_ic;
  165.         while(p){
  166.             c=p->code;
  167.             t=p->typf;
  168.             ic_count++;
  169.             if(c==LABEL&&report_suspicious_loops&&p->next&&p->next->code==BRA&&p->next->typf==t){
  170.               error(208);report_suspicious_loops=0;
  171.             }
  172.             if((p->q1.flags&(KONST|DREFOBJ))==KONST){
  173.                 if((p->q2.flags&KONST)||!p->q2.flags){
  174.                     struct IC *old=p->prev;
  175.                     if(fold(p)){ changed=1; p=old;continue;}
  176.                     p=p->next;continue;
  177.                 }else{
  178.                     if(c==ADD||c==MULT||(c>=OR&&c<=AND)){ /*  const nach rechts   */
  179.                         if(DEBUG&1024){ printf("swapped commutative op:\n");pric2(stdout,p);}
  180.                         o=p->q1;p->q1=p->q2;p->q2=o;
  181.                     }
  182.                 }
  183.             }
  184.             if((p->q2.flags&(KONST|DREFOBJ))==KONST){
  185.             /*  algebraische Optimierungen  */
  186.                 eval_const(&p->q2.val,t);
  187.                 if(zleqto(vlong,l2zl(0L))&&zuleqto(vulong,ul2zul(0UL))&&zdeqto(vdouble,d2zd(0.0))) null=1; else null=0;
  188.                 if(zleqto(vlong,l2zl(1L))&&zuleqto(vulong,ul2zul(1UL))&&zdeqto(vdouble,d2zd(1.0))) eins=1; else eins=0;
  189.                 if(zleqto(vlong,l2zl(-1L))&&zdeqto(vdouble,d2zd(-1.0))) eins=-1;
  190.                 if(eins<0&&(c==MULT||c==DIV)){
  191.                     if(DEBUG&1024){ printf("MULT/DIV with (-1) converted to MINUS:\n");pric2(stdout,p);}
  192.                     p->code=c=MINUS;p->q2.flags=0;
  193.                     changed=1;
  194.                 }
  195. #if 0
  196.                 if(c==SUB){
  197.                 /*  VORSICHT: Das funktioniert bei bestimmten Werten nicht! */
  198.                     if(DEBUG&1024){ printf("SUB converted to ADD:\n");pric2(stdout,p);}
  199.                     p->code=c=ADD; calc(MINUS,t,&p->q2.val,0,&p->q2.val,p);
  200.                     changed=1;
  201.                 }
  202. #endif
  203.                 if((eins>0&&(c==MULT||c==DIV))||(null&&(c==ADD||c==SUB||c==ADDI2P||c==SUBIFP||c==LSHIFT||c==RSHIFT||c==OR||c==XOR))){
  204.                     if(DEBUG&1024){ printf("operation converted to simple assignment:\n");pric2(stdout,p);}
  205.                     if(c==ADDI2P||c==SUBIFP) p->typf=t=POINTER;
  206.                     p->code=c=ASSIGN;p->q2.flags=0;p->q2.val.vlong=sizetab[t&NQ];
  207.                     changed=1;
  208.                 }
  209.                 if(null&&(c==MULT||c==DIV||c==MOD||c==AND)){